package com.googlecode.restitory.api.gae;

import java.util.List;

import com.google.appengine.api.datastore.DeleteContext;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.PostDelete;
import com.google.appengine.api.datastore.PostPut;
import com.google.appengine.api.datastore.PreDelete;
import com.google.appengine.api.datastore.PrePut;
import com.google.appengine.api.datastore.PutContext;
import com.google.gson.JsonObject;
import com.googlecode.restitory.gae.filter.util.JsonUtil;

public class JsonEntityCallback {

	private String convertContext(DeleteContext ctx) {
		Key key = ctx.getCurrentElement();
		if (!key.getKind().startsWith("r-/")) {
			return null;
		}
		String path = DatastoreJsonService.keyToString(key);
		return path;
	}

	private JsonObject convertContext(PutContext ctx) {
		Entity entity = ctx.getCurrentElement();
		if (!entity.getKey().getKind().startsWith("r-/")) {
			return null;
		}
		JsonObject json = DatastoreJsonService.entityToJson(entity);
		return json;
	}

	@PrePut
	public void prePut(PutContext ctx) {
		JsonObject json = convertContext(ctx);
		if (json == null) {
			return;
		}
		String path = (String) JsonUtil.getJsonValue(json.get("_self"));
		List<JsonCallback> list = JsonCallbackHandler.instance().get(path);
		JsonDesc desc = JsonDesc.create();
		for (JsonCallback callback : list) {
			callback.prePut(json, desc);
		}

		DatastoreJsonService.jsonToEntity(json, ctx.getCurrentElement(), desc);
	}

	@PostPut
	public void postPut(PutContext ctx) {
		JsonObject json = convertContext(ctx);
		if (json == null) {
			return;
		}

		String path = (String) JsonUtil.getJsonValue(json.get("_self"));
		List<JsonCallback> list = JsonCallbackHandler.instance().get(path);
		for (JsonCallback callback : list) {
			callback.postPut(json);
		}
	}

	@PreDelete
	public void preDelete(DeleteContext ctx) {
		String path = convertContext(ctx);
		if (path == null) {
			return;
		}

		List<JsonCallback> list = JsonCallbackHandler.instance().get(path);
		for (JsonCallback callback : list) {
			callback.preDelete(path);
		}
	}

	@PostDelete
	public void postDelete(DeleteContext ctx) {
		String path = convertContext(ctx);
		if (path == null) {
			return;
		}

		List<JsonCallback> list = JsonCallbackHandler.instance().get(path);
		for (JsonCallback callback : list) {
			callback.postDelete(path);
		}
	}
}
